前面介紹 Deployment 時有提到,Deployment 可以設定 replicas 來決定需要維持多少個 Pod,當其中一個 Pod 發生問題或被刪除時,Deployment 會重新建立 Pod,讓實際的 Pod 數量維持在設定的數量。
但實際運行服務時,所需要的 Pod 數量不一定永遠相同。例如平常可能只需要 2 個 Pod,但當大量使用者同時存取服務時,原本的 Pod 數量可能不足以處理突然增加的負載。
如果每次都需要手動修改 replicas 就會相當麻煩,因此 Kubernetes 提供了 HPA(Horizontal Pod Autoscaler)來根據負載自動調整 Pod 數量。
HPA(Horizontal Pod Autoscaler)中文通常稱為水平 Pod 自動擴縮,可以根據 CPU、Memory 或其他指標,自動調整 Deployment、StatefulSet 等工作負載的副本數量。
簡單來說,Deployment 負責維持指定的 Pod 數量,而 HPA 則可以根據目前的負載,動態決定 Deployment 應該維持多少個 Pod。
例如:
Deployment
replicas: 2
↓
維持 2 個 Pod
↓
CPU 使用率上升
↓
HPA 判斷目前 Pod 數量不足
↓
增加 replicas
↓
Deployment 建立更多 Pod
當負載降低後,HPA 也可以減少副本數量,避免一直維持不需要的 Pod。
因此 HPA 並不是自己直接建立或刪除 Pod,而是調整工作負載所需要的副本數量,再由 Deployment 等控制器負責建立或移除 Pod。
HPA 如果要根據 CPU、Memory 等資源使用量進行調整,就需要取得相關的 Metrics。
在 DAY6 中為了查看 Pod 的資源使用情形,我們已經安裝過 metrics-server,如果還沒有安裝,可以在 Minikube 中使用:
minikube addons enable metrics-server
等待 Metrics Server 啟動並收集一段時間的資料後,可以使用:
kubectl top pods
查看目前 Pod 的 CPU 與 Memory 使用情形。
接著建立一個 Deployment 來測試 HPA:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hpa-demo
spec:
replicas: 1
selector:
matchLabels:
app: hpa-demo
template:
metadata:
labels:
app: hpa-demo
spec:
containers:
- name: hpa-demo
image: nginx
resources:
requests:
cpu: "20m"
limits:
cpu: "200m"
套用:
kubectl apply -f hpa-demo.yaml
這裡將 Deployment 初始的 replicas 設定為 1,並設定 CPU request:
requests:
cpu: "20m"
這個設定除了代表容器所請求的 CPU 資源之外,在使用 CPU utilization 作為 HPA 指標時也相當重要。
接著使用以下YAML建立 HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hpa-demo
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
其中:
averageUtilization: 50:CPU 平均使用率目標設定為 50%minReplicas: 1:最少維持 1 個 PodmaxReplicas: 5:最多擴展到 5 個 PodscaleTargetRef:指定 HPA 要調整的工作負載,這裡設定為 hpa-demo Deployment套用完成後,可以使用:
kubectl get hpa
查看 HPA:

TARGETS 中會顯示目前的 CPU 使用率與設定的目標值。
例如:
10% / 50%
代表目前大約為 10%,而 HPA 設定的目標為 50%。
前面 Deployment 中設定:
requests:
cpu: "20m"
假設 Pod 目前實際使用:
12m CPU
那麼相對於 CPU request 的使用率就是:
12m / 20m = 60%
當實際使用率高於 HPA 設定的 50% 目標時,HPA 就會根據目前的使用情況計算需要的副本數量。
因此在使用 CPU utilization 作為 HPA 指標時,如果沒有正確設定 CPU request,HPA 就可能無法取得計算這個百分比所需要的基準。
使用下面兩個 YAML 設定檔來建立 Service 和測試用 Pod。
apiVersion: v1
kind: Service
metadata:
name: hpa-demo
spec:
selector:
app: hpa-demo
ports:
- port: 80
targetPort: 80
apiVersion: v1
kind: Pod
metadata:
name: load-generator
spec:
containers:
- name: load-generator
image: busybox:1.36
command:
- /bin/sh
- -c
- "while true; do wget -q -O- http://hpa-demo; done"
restartPolicy: Never
可以持續查看 HPA 的狀態:
kubectl get hpa -w
同時也可以觀察 Pod 數量:
kubectl get pods -w
當服務產生足夠的 CPU 負載後,可以觀察 HPA 是否開始提高副本數量。
負載提高一段時間後,可能會看到 Deployment 建立新的 Pod:
當負載降低後,HPA 不會馬上將 Pod 減少,而是會等待一段時間確認負載確實下降,再逐漸縮減副本數量,避免因為短時間的負載變化而頻繁建立與刪除 Pod。
輸入kubectl delete pod load-generator
之後再觀察 HPA
最後可以將 Deployment 與 HPA 的工作簡單整理成:
Metrics Server
↓
取得 CPU / Memory 等使用資訊
↓
HPA
↓
調整 Deployment 的 replicas
↓
Deployment
↓
建立或減少 Pod
Deployment 本身負責讓實際運行的 Pod 數量符合指定的副本數量,而 HPA 則會根據負載動態調整這個數量。
透過 HPA,就可以讓 Kubernetes 在負載提高時自動增加 Pod,負載降低時再減少 Pod,不需要每次都由使用者手動修改 Deployment 的 replicas。